#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# html_buffer.py 
#
#  Copyright (c) 2007 INdT (Instituto Nokia de Technologia)
#                2007 Kenneth Christiansen
#
#  Author: Kenneth Rohde Christiansen <kenneth.christiansen@gmail.com>
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License as
#  published by the Free Software Foundation; either version 2 of the
#  License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
#  USA

class HtmlBuffer(object):

    buffer = ""

    def __init__(self):
        self.offsets = {}
        self.offsets[0] = (0, [])
        self.last_offset = 0


    def set_text(self, text):
        buffer = ""
        self.offsets = {}
        self.offsets[0] = (0, [])
        self.last_offset = 0

        self.insert(text)


    def insert(self, text):
        self.buffer = self.buffer + text

        buffer_offset, open_tags = self.offsets[self.last_offset]

        if len(self.buffer) - buffer_offset > 100:
            conti = True

            while conti:
                conti = self.update_offsets()

        #print "Inserted ('%s')" % text.replace("\n", "\\n")


    def update_offsets(self):
        buffer_offset, open_tags = self.offsets[self.last_offset]
        buffer_slice = self.buffer[buffer_offset:]

        offset, start_tag_list = self.get_offset(buffer_slice, 50, open_tags)

        if offset == 0:
            return False

        self.offsets[self.last_offset + 50] = (buffer_offset + offset, start_tag_list)
        self.last_offset = self.last_offset + 50

        return True


    def get_offset(self, buffer, offset_to_find, open_tags):
        start_offset = offset_to_find

        start_text = 0

        text_iter = 0
        true_iter = 0
        do_count = True

        buffer_iter = iter(buffer)

        previous_char = None
        try:
            char = buffer_iter.next()
        except StopIteration, e:
            char = None
        end_tag = False

        current_tag = ""
        end_tag_list = []
        start_tag_list = open_tags[:]

        while char != None:
            if previous_char == "<" and char == "/":
                end_tag = True

            if char == "<":
                do_count = False

            if char == ">":
                do_count = True

                if end_tag == True:
                    end_tag = False
                    start_tag_list.remove(current_tag[2:])

                elif previous_char != "/":
                    start_tag_list.append(current_tag[1:])

                current_tag = ""

            if do_count == False:
                current_tag = current_tag + char

            if text_iter == start_offset:
                start_text = true_iter
                break

            true_iter = true_iter + 1

            if do_count and char != ">":
                text_iter = text_iter + 1

            try:
                previous_char = char
                char = buffer_iter.next()
            except StopIteration, e:
                if text_iter == start_offset:
                    start_text = len(buffer)
                break

        return (start_text, start_tag_list)

    def _lookup(self, offset):
        lookup_failed = True
        diff = 0

        while lookup_failed:
            remain = (offset % 50) + diff
            lookup = offset - remain

            try:
                buffer_offset, open_tags = self.offsets[lookup]
                lookup_failed = False
            except KeyError, e:
                diff = diff + 50

        return (buffer_offset, remain, open_tags)

    def get_slice(self, start_offset, end_offset, convert_html=False):

        buffer_start_offset, start_remain, start_open_tags = self._lookup(start_offset)

        final_buffer_start_offset, buffer_start_tags = self.get_offset(self.buffer[buffer_start_offset:], \
            start_remain, start_open_tags)

        buffer_end_offset, end_remain, end_open_tags = self._lookup(end_offset)

        final_buffer_end_offset, buffer_end_tags = self.get_offset(self.buffer[buffer_end_offset:], \
            end_remain, end_open_tags)

        final_buffer_start_offset = final_buffer_start_offset + buffer_start_offset
        final_buffer_end_offset = final_buffer_end_offset + buffer_end_offset

        buffer_end_tags.reverse()
        buffer_start_tags.reverse()

        # can probably be removed now
        if final_buffer_end_offset == 0:
            print "DONT REMOVE"
            final_buffer_end_offset = len(self.buffer)

        #print "---------------------------------"
        #print "Iter asked: (%s, %s)" % (start_offset, end_offset)
        #print "Iter in buffer: (%s, %s)" % (final_buffer_start_offset, final_buffer_end_offset)
        #print "Buffer: '%s'" % self.buffer
        #print "Length: %s" % len(self.buffer)

        text = self.buffer[final_buffer_start_offset:final_buffer_end_offset]

        for tag in buffer_start_tags:
            text = "<" + tag + ">" + text

        for tag in buffer_end_tags:
            text = text + "</" + tag + ">"

        if convert_html == True:
            return self.convert_html_to_text(text)
        else:
            return text


    def convert_html_to_text(self, text):
        text = text.replace("<b>", "*")
        text = text.replace("</b>", "*")
        text = text.replace("<i>", "/")
        text = text.replace("</i>", "/")
        text = text.replace("<u>", "_")
        text = text.replace("</u>", "_")
        text = text.replace("<img alt=\"", "")
        text = text.replace("\"/> ", "")

        return text
